package brad.zimmerman.dungeon.game;

import java.util.Random;

import android.graphics.PointF;
import android.util.Log;

//Populates the gameboard with the game objects.
//Called from the reference image class
public class ClassGameBoard {
	ClassDrawingHolder Draws = new ClassDrawingHolder();
	Random random = new Random(System.currentTimeMillis());
	int[][] objPos;
	int[][] glyphPos;
	ClassEnemyStats[][] enemyPos;
	int[][] shroudPos;
	int[][] debrisPos;
	ClassShop[][] shopPos;
	ClassAltar[][] altarPos;
	ClassGameBoard(int[][] map, int playerX, int playerY, boolean tutorial, ClassGameStats playerStats){
		int tiles = 20;
		/*
		int[][] mapTemplate = {
				{0,0,0,1,%,%,%,1,0,0,0,1,x,x,x,x,x,x,x,0}, //0
				{0,P,0,x,%,S,%,x,0,%,0,1,0,1,1,1,1,1,0,0}, //1
				{0,0,0,1,%,%,%,1,0,0,0,1,0,1,0,0,0,1,0,0}, //2
				{1,1,1,1,1,1,1,1,1,x,1,1,G,1,x,1,0,1,S,0}, //3
				{0,0,0,x,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0}, //4
				{0,%,0,x,0,0,G,0,x,G,0,1,x,0,0,0,x,1,0,0}, //5
				{0,0,0,x,0,0,0,0,1,0,%,1,1,1,1,1,1,1,x,1}, //6
				{1,x,1,1,1,1,1,1,1,1,1,1,S,0,0,A,0,0,0,0}, //7
				{0,G,1,0,0,0,0,x,1,0,0,0,0,0,0,0,0,0,0,0}, //8
				{0,0,1,0,%,0,1,0,1,x,1,1,1,1,1,1,1,1,1,1}, //9
				{0,1,1,0,%,0,1,0,1,0,0,%,0,x,0,%,0,0,0,0}, //10
				{0,0,x,0,0,0,1,0,1,0,0,%,0,x,0,%,0,0,0,0}, //11
				{1,1,1,1,1,1,1,x,1,1,1,1,1,1,1,0,G,1,1,x}, //12
				{0,0,0,0,x,0,0,0,1,%,0,0,0,0,1,1,1,1,0,0}, //13
				{0,%,%,0,x,0,0,0,1,%,%,%,0,0,x,0,0,1,S,0}, //14
				{0,0,0,0,x,0,0,0,1,%,0,0,0,0,1,0,0,1,0,0}, //15
				{1,1,1,x,1,1,1,1,1,1,1,1,x,1,1,0,0,1,0,0}, //16
				{%,0,0,0,1,0,x,S,1,0,0,x,0,0,1,0,0,x,0,0}, //17
				{%,0,0,0,x,0,x,0,x,0,0,x,0,%,1,0,0,1,0,0}, //18
				{%,0,0,0,1,0,x,0,1,0,0,x,0,%,1,0,0,1,0,S}  //19
		};    // 0.1.2.3.4.5.6.7.8.9.10111213141516171819
		 */
		int selectorX;
		int selectorY;
		int enemyType, glyphtype;
		int count = 0;
		objPos = new int [tiles][tiles];
		glyphPos = new int [tiles][tiles];
		enemyPos = new ClassEnemyStats[tiles][tiles];
		shroudPos = new int[tiles][tiles];
		debrisPos = new int[tiles][tiles];
		shopPos = new ClassShop[tiles][tiles];
		altarPos = new ClassAltar[tiles][tiles];
		boolean[] glyph_used = new boolean[Draws.glyphImages.length];
		for(int i = 0; i< Draws.glyphImages.length;i++){
			glyph_used[i] = false;
		}
		if(playerStats.currentGlyphs[0]!=0){
			glyph_used[playerStats.currentGlyphs[0]-1] = true;
		}
		for(int y = 0; y< tiles; y++){
			for (int x=0; x<tiles; x++){
				this.objPos[x][y]= 0;
				this.glyphPos[x][y]= 0;
				this.debrisPos[x][y]= 0;
				this.shopPos[x][y]= new ClassShop(0,0);
				this.altarPos[x][y]= new ClassAltar(0,0,0);
				this.shroudPos[x][y]= 2;
				this.enemyPos[x][y]= new ClassEnemyStats(0,0,0,0,false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
			}
		}
		setMonsterLevel(new PointF(3,1),3,1);
		setMonsterLevel(new PointF(7,1),3,2);
		setMonsterLevel(new PointF(9,3),2,1);
		setMonsterLevel(new PointF(8,5),1,2);
		setMonsterLevel(new PointF(3,4),0,1);
		setMonsterLevel(new PointF(3,5),0,1);
		setMonsterLevel(new PointF(3,6),0,1);
		setMonsterLevel(new PointF(1,7),3,3);
		setMonsterLevel(new PointF(2,11),2,3);
		setMonsterLevel(new PointF(7,8),0,3);
		setMonsterLevel(new PointF(7,12),1,4);
		setMonsterLevel(new PointF(4,13),2,4);
		setMonsterLevel(new PointF(4,14),2,4);
		setMonsterLevel(new PointF(4,15),2,4);
		setMonsterLevel(new PointF(3,16),3,5);
		setMonsterLevel(new PointF(4,18),2,5);
		setMonsterLevel(new PointF(6,17),3,5);
		setMonsterLevel(new PointF(6,18),3,5);
		setMonsterLevel(new PointF(6,19),3,5);
		setMonsterLevel(new PointF(8,18),2,6);
		setMonsterLevel(new PointF(11,17),3,6);
		setMonsterLevel(new PointF(11,18),3,6);
		setMonsterLevel(new PointF(11,19),3,6);
		setMonsterLevel(new PointF(12,16),1,6);
		setMonsterLevel(new PointF(14,14),0,7);
		setMonsterLevel(new PointF(17,17),3,7);
		setMonsterLevel(new PointF(19,12),2,7);
		setMonsterLevel(new PointF(13,10),1,7);
		setMonsterLevel(new PointF(13,11),0,7);
		setMonsterLevel(new PointF(9,9),0,8);
		setMonsterLevel(new PointF(18,6),2,8);
		setMonsterLevel(new PointF(18,0),3,8);
		setMonsterLevel(new PointF(17,0),3,8);
		setMonsterLevel(new PointF(16,0),3,8);
		setMonsterLevel(new PointF(15,0),3,8);
		setMonsterLevel(new PointF(14,0),3,8);
		setMonsterLevel(new PointF(13,0),3,8);
		setMonsterLevel(new PointF(12,0),1,9);
		setMonsterLevel(new PointF(12,5),2,9);
		setMonsterLevel(new PointF(6,14),3,9);
		setMonsterLevel(new PointF(16,5),0,9);
		setMonsterLevel(new PointF(14,3),3,10);
		glyphPos[9][5] = 10;
		glyphPos[6][5] = 8;
		glyphPos[1][18] = 12;
		glyphPos[16][12] = 5;
		glyphPos[12][3] = 9;
		//Gold
		objPos[4][0] = 2;
		objPos[5][0] = 2;
		objPos[6][0] = 2;
		objPos[4][1] = 2;
		objPos[6][1] = 2;
		objPos[4][2] = 2;
		objPos[5][2] = 2;
		objPos[6][2] = 2;
		objPos[10][6] = 2;
		objPos[13][18] = 2;
		objPos[13][19] = 2;
		objPos[9][13] = 2;
		objPos[9][14] = 2;
		objPos[9][15] = 2;
		//Atk Up
		objPos[9][1] = 1;
		objPos[15][10] = 1;
		objPos[15][11] = 1;
		objPos[11][10] = 1;
		objPos[11][11] = 1;
		//Health Up
		objPos[1][5] = 4;
		objPos[0][17] = 4;
		objPos[0][18] = 4;
		objPos[0][19] = 4;
		//Mana Up
		objPos[4][9] = 6;
		objPos[4][10] = 6;
		//HP Potion
		objPos[1][14] = 3;
		objPos[10][14] = 3;
		//Mana Potion
		objPos[2][14] = 5;
		objPos[11][14] = 5;
		
		//Increase Health
		shopPos[5][1] = new ClassShop(playerStats.shopTech[2],2);
		shopPos[7][17] = new ClassShop(playerStats.shopTech[6],6);
		shopPos[19][19] = new ClassShop(2,18);
		shopPos[18][14] = new ClassShop(playerStats.shopTech[7],7);
		shopPos[12][7] = new ClassShop(playerStats.shopTech[3],3);
		shopPos[18][3] = new ClassShop(2,11);
		
		//Altars
		altarPos[15][7] = new ClassAltar(playerStats.playerTech[6],playerStats.playerTech[7],10);

	}
	public void setMonsterLevel(PointF location, int monster, int level){
		enemyPos[(int) location.x][(int) location.y] = new ClassEnemyStats(
				Draws.enemyBaseStats[Draws.levelMonsters[0][monster]][0],
				Draws.enemyBaseStats[Draws.levelMonsters[0][monster]][1],
				Draws.enemyBaseStats[Draws.levelMonsters[0][monster]][2],
				Draws.levelMonsters[0][monster]+1,
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][0], 
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][1], 
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][2], 
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][3], 
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][4], 
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][5],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][6],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][7],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][8],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][9],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][10],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][11],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][12],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][13],
				Draws.enemyAbilityStats[Draws.levelMonsters[0][monster]][14]);
		enemyPos[(int) location.x][(int) location.y].setLevel(level);
	}
	ClassGameBoard(int[][] map, int playerX, int playerY, int tiles, ClassGameStats playerStats){
		int selectorX;
		int selectorY;
		int enemyType, glyphtype;
		int count = 0;
		objPos = new int [tiles][tiles];
		glyphPos = new int [tiles][tiles];
		enemyPos = new ClassEnemyStats[tiles][tiles];
		shroudPos = new int[tiles][tiles];
		debrisPos = new int[tiles][tiles];
		shopPos = new ClassShop[tiles][tiles];
		altarPos = new ClassAltar[tiles][tiles];
		boolean[] glyph_used = new boolean[Draws.glyphImages.length];
		for(int i = 0; i< Draws.glyphImages.length;i++){
			glyph_used[i] = false;
		}
		if(playerStats.currentGlyphs[0]!=0){
			glyph_used[playerStats.currentGlyphs[0]-1] = true;
		}
		for(int y = 0; y< tiles; y++){
			for (int x=0; x<tiles; x++){
				this.objPos[x][y]= 0;
				this.glyphPos[x][y]= 0;
				this.debrisPos[x][y]= 0;
				this.shopPos[x][y]= new ClassShop(0,0);
				this.altarPos[x][y]= new ClassAltar(0,0,0);
				this.shroudPos[x][y]= 2;
				this.enemyPos[x][y]= new ClassEnemyStats(0,0,0,0,false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
			}
		}
		//Log.d("RefImage","Stuff Initialized");
		//Puts the glyphs on the board
		while(count< playerStats.glyph_quantity){
				selectorX = random.nextInt( tiles );
				selectorY = random.nextInt( tiles );
				glyphtype = random.nextInt( Draws.glyphImages.length );
				if ((glyphPos[selectorX][selectorY] == 0) && (map[selectorX][selectorY] == 0) && Draws.glyphUnlocked(glyphtype, playerStats.unlockLevel) 
						&& ((playerX != selectorX) && (playerY != selectorY)) && (Draws.glyphStrings[glyphtype] != "Empty")
						&& (glyph_used[glyphtype] == false)){
					glyphPos[selectorX][selectorY] = glyphtype+1;
					glyph_used[glyphtype] = true;
					count++;
			}
		}
		count = 0;
		//Log.d("RefImage","Glyphs Set");
		//System.out.println(playerX + " " + playerY);
		//Puts the objects on the board
		for (int pos = 0; pos<playerStats.objectQuantity.length;pos++){
			while(count< (playerStats.objectQuantity[pos] + playerStats.xtraItems)){
				selectorX = random.nextInt( tiles );
				selectorY = random.nextInt( tiles );
				enemyType = random.nextInt( 4 );
				if ((glyphPos[selectorX][selectorY] == 0) && (objPos[selectorX][selectorY] == 0) && (map[selectorX][selectorY] == 0) 
						&& ((playerX != selectorX) && (playerY != selectorY))){
					objPos[selectorX][selectorY] = pos+1;
					count++;
				}
			}
			count = 0;
		}
		//Log.d("RefImage","Objects Set");
		count = 0;
		int lvlSetter = 1;
		int numEnemies = (39 + (int)Math.floor((1+Draws.levelDifficulty[playerStats.player_level]) / 10));
		//Puts the enemies on the board
		while(count < numEnemies){
				selectorX = random.nextInt( tiles );
				selectorY = random.nextInt( tiles );
				//If the enemy is not being placed on a player, item, wall, or other enemy, place that enemy.
				if ((glyphPos[selectorX][selectorY] == 0) && (enemyPos[selectorX][selectorY].returnMonster() == 0) && (objPos[selectorX][selectorY] == 0) && (map[selectorX][selectorY] == 0) 
						&& ((playerX != selectorX) && (playerY != selectorY))){
					enemyType = random.nextInt( 4 );
					//System.out.println("Player: " + playerX + " " + playerY);
					//System.out.println("Enemy: " + selectorX + " " + selectorY);
					//System.out.println("Count: " + count + " enemyType: " + enemyType);
					//enemyPos[selectorX][selectorY] = new enemyStats(Draws.enemyBaseStats[Draws.enemyBaseStats[playerStats.player_level][enemyType]][0],Draws.enemyBaseStats[Draws.enemyBaseStats[playerStats.player_level][enemyType]][1],Draws.enemyBaseStats[Draws.enemyBaseStats[playerStats.player_level][enemyType]][2],Draws.enemyBaseStats[playerStats.player_level][enemyType]+1);
					enemyPos[selectorX][selectorY] = new ClassEnemyStats(
							Draws.enemyBaseStats[Draws.levelMonsters[playerStats.player_level][enemyType]][0],
							Draws.enemyBaseStats[Draws.levelMonsters[playerStats.player_level][enemyType]][1],
							Draws.enemyBaseStats[Draws.levelMonsters[playerStats.player_level][enemyType]][2],
							Draws.levelMonsters[playerStats.player_level][enemyType]+1,
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][0], 
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][1], 
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][2], 
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][3], 
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][4], 
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][5],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][6],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][7],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][8],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][9],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][10],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][11],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][12],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][13],
							Draws.enemyAbilityStats[Draws.levelMonsters[playerStats.player_level][enemyType]][14]);
					if(playerStats.allEnemiesCowards){
						enemyPos[selectorX][selectorY].coward = true;
					}
					switch(count){
						case 10: lvlSetter++; break;
						case 15: lvlSetter++; break;
						case 19: lvlSetter++; break;
						case 23: lvlSetter++; break;
						case 27: lvlSetter++; break;
						case 30: lvlSetter++; break;
						case 33: lvlSetter++; break;
						case 36: lvlSetter++; break;
						case 38: lvlSetter++; break;
					}
					
					enemyPos[selectorX][selectorY].setLevel(lvlSetter);
					//enemyPos[selectorX][selectorY].printStats();
					count++;
				}
		}
		//Log.d("RefImage","Enemies Set");
		boolean[] techshops = new boolean[20];
		for (int i = 0; i < techshops.length ; i++){
			techshops[i] = false;
		}
		int sellingItem;
		int numberOfItems = Draws.itemSuffixes.length+9;
		for(int i = 0; i< (playerStats.shopRate);){
			selectorX = random.nextInt( tiles );
			selectorY = random.nextInt( tiles );
			
			
			sellingItem = random.nextInt(numberOfItems);
			while((sellingItem<12 && techshops[sellingItem] == true) || (playerStats.hitIncreaseAttack && sellingItem == 11)){
				sellingItem = random.nextInt(numberOfItems);
			}
			if(sellingItem < 12){techshops[sellingItem] = true;}
			
			if ((glyphPos[selectorX][selectorY] == 0) && (objPos[selectorX][selectorY] == 0) && (map[selectorX][selectorY] == 0) 
					&& ((playerX != selectorX) && (playerY != selectorY))&& (enemyPos[selectorX][selectorY].returnMonster() == 0) && (shopPos[selectorX][selectorY].getItem() == 0)){
				if(sellingItem<10){
					shopPos[selectorX][selectorY] = new ClassShop(playerStats.shopTech[sellingItem],sellingItem+1);
				}else{
					shopPos[selectorX][selectorY] = new ClassShop((int) Math.floor(playerStats.player_level/3),sellingItem+1);
				}
				i++;
			}
		}
		//Log.d("RefImage","Shops Set");
		int[] altars = new int[playerStats.altarRate];
		int altarGod = 0;
		for(int i = 0; i< (playerStats.altarRate);){
			selectorX = random.nextInt( tiles );
			selectorY = random.nextInt( tiles );
			while(inArray(altars,altarGod)){
				altarGod = random.nextInt(5 + playerStats.playerTech[5])+1;
			}
			altars[i] = altarGod;
			if ((glyphPos[selectorX][selectorY] == 0) && (objPos[selectorX][selectorY] == 0) && (map[selectorX][selectorY] == 0) 
					&& ((playerX != selectorX) && (playerY != selectorY))&& (enemyPos[selectorX][selectorY].returnMonster() == 0)
					&& (shopPos[selectorX][selectorY].getItem() == 0) && (altarPos[selectorX][selectorY].getGod() == 0)){
				altarPos[selectorX][selectorY] = new ClassAltar(playerStats.playerTech[6],
						playerStats.playerTech[7],
						altarGod);
				i++;
			}
		}
		//Log.d("RefImage","Altars Set");
		//System.out.println("Done");
	}
	public boolean inArray(int[] array, int number){
		for (int i = 0; i < array.length; i ++){
			if (array[i] == number){
				return true;
			}
		}
		return false;
	}
	public int[][] returnMap(){
		return this.objPos;
	}
}
